package de.eridea.learning.usermanagement.webinterface;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;

import de.eridea.learning.java.usermanagement.logic.UserService;
import de.eridea.learning.java.usermanagement.logic.exception.NoSuchUserException;
import de.eridea.learning.java.usermanagement.logic.exception.VerificationFailedException;
import de.eridea.learning.java.usermanagement.logic.to.GroupData;
import de.eridea.learning.java.usermanagement.logic.to.UserData;
import de.eridea.learning.java.usermanagement.logic.to.UserDataLinked;

public class LoginHandler {

	private UserBean userBean;

	private String loginName;

	private String pwd;

	private UserService userService;

	public String login() {
		if (userService == null) {
			throw new IllegalStateException(
					"userService is null. Set userService before logging in.");
		}
		if (userBean == null) {
			throw new IllegalStateException(
					"userBean is null. Set userBean before logging in.");
		}
		String result = null;
		if (userBean.isLoggedIn()) {
			result = "you-were-logged-in";
		} else {
			try {
				UserDataLinked user = userService.login(loginName, pwd);
				Method[] methods = UserData.class.getMethods();
				for (int k = 0; k < methods.length; k++) {
					if ((methods[k].getParameterTypes().length == 0)
							&& (methods[k].getName().startsWith("get"))
							&& (!methods[k].getReturnType().equals(Void.class))) {
						try {
							userBean.getClass()
									.getMethod(
											"set"
													+ methods[k].getName()
															.substring(3),
											new Class[] { String.class })
									.invoke(userBean,
											methods[k].invoke(user).toString());
						} catch (NoSuchMethodException e) {

						} catch (IllegalArgumentException e) {
							e.printStackTrace();
							throw new RuntimeException(e.getMessage(),
									e.getCause());
						} catch (SecurityException e) {
							e.printStackTrace();
							throw new RuntimeException(e.getMessage(),
									e.getCause());
						} catch (IllegalAccessException e) {
							e.printStackTrace();
							throw new RuntimeException(e.getMessage(),
									e.getCause());
						} catch (InvocationTargetException e) {
							e.printStackTrace();
							throw new RuntimeException(e.getMessage(),
									e.getCause());
						}
					}
				}
				Set<GroupData> groups = user.getGroups();
				Collection<String> groupNames = new ArrayList<String>(groups.size());
				for(GroupData group : groups) {
					groupNames.add(group.getGroupName());
				}
				userBean.setGroups(groupNames);
				userBean.setLoggedIn(true);
				result = "accept";
			} catch (NoSuchUserException nsu) {
				result = "unknown";
			} catch (VerificationFailedException vf) {
				result = "deny";
			}
		}
		pwd = null;
		return result;
	}

	public String logout() {
		if (userService == null) {
			throw new IllegalStateException(
					"userService is null. Set userService before logging in.");
		}
		if (userBean == null) {
			throw new IllegalStateException(
					"userBean is null. Set userBean before logging in.");
		}
		String result = null;
		if (! userBean.isLoggedIn()) {
			result = "notLoggedIn";
		} else {
			userBean.setLoggedIn(false);
			result = "logout";
		}
		return result;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public void setUserBean(UserBean userBean) {
		this.userBean = userBean;
	}
}
